package com.origin.utils;

import static android.content.Context.MODE_PRIVATE;

import android.app.Application;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.IntDef;
import androidx.annotation.RequiresApi;
import androidx.core.content.FileProvider;

import com.origin.utils.log.LogUtils;
import com.origin.utils.log.LogVariateUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.channels.FileChannel;

public class FileUtils {


    public static void loadPath(Application context) {
        PathUtils.loadPath(context);
    }

    //默认保存到data/data/包名/files/目录下
    public static String saveFileToOpenFile(byte[] bytes, String fileName, Context context) {
        try {
            String md5fileName = MD5Utils.md5(fileName);
            String filePath = "/data/data/" + context.getPackageName() + "/files/" + md5fileName + ".jpg";
            File file = new File(filePath);
            if (file.exists()) {
                return "file://" + filePath;
            }
            FileOutputStream outputStream = context.openFileOutput(md5fileName + ".jpg", MODE_PRIVATE);
            outputStream.write(bytes);
            outputStream.flush();
            return "file://" + filePath;
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "";

    }


    public static void deleteFolder(File folder) {

        if (folder.isDirectory()) {
            File[] files = folder.listFiles();
            if (files != null) {
                for (File file : files) {
                    deleteFolder(file);
                }
            }
        }
        folder.delete();
    }

    public static void deleteFolder(String path) {

        deleteFolder(new File(path));
    }


    public static void strToFileAppend(String str, String fileName) {
        writeToFile(str, PathUtils.filesPath, fileName, true);
    }

    public static void strToFile(String str, String fileName) {
        writeToFile(str, PathUtils.filesPath, fileName, false);
    }

    public static String readToFile(String filePathName) {
        FileReader fr = null;
        try {
            File file = new File(filePathName);
            if (!file.exists()) {
                return "";
            }
            long n = LogVariateUtils.getInstance().getFileSize();
            long len = file.length();
            long skip = len - n;
            fr = new FileReader(file);
            fr.skip(Math.max(0, skip));
            char[] cs = new char[(int) Math.min(len, n)];
            fr.read(cs);
            return new String(cs).trim();
        } catch (Throwable ex) {
            Log.e("LogFileUtils", "readLogText 1 异常 " + ex);
            ex.printStackTrace();
        } finally {
            try {
                if (fr != null)
                    fr.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return "";
    }

    public static byte[] fileConvertByteArray(File file) {

        try {
            FileInputStream fileInputStream = new FileInputStream(file);
            byte[] fileBytes = new byte[(int) file.length()];
            fileInputStream.read(fileBytes);
            fileInputStream.close();
            return fileBytes;
        } catch (IOException e) {
            e.printStackTrace();
        }

        return new byte[0];
    }

    public static void byteToFile(byte[] bytes, String path) {
        try {
            // 根据绝对路径初始化文件
            File localFile = new File(path);
            Log.e("保存文件", "地址 " + localFile.getAbsolutePath());
            if (!localFile.exists()) {
                boolean isCreateNewFile = localFile.createNewFile();
                Log.e("保存文件", "isCreateNewFile " + isCreateNewFile);
            }
            // 输出流
            OutputStream os = new FileOutputStream(localFile);
            os.write(bytes);
            os.close();
        } catch (Exception e) {
            e.printStackTrace();
            Log.e("保存文件", "Exception " + e);
        }
    }


    public static void writeToFile(String str, File file, boolean append) {
        byte[] bytes = new byte[0];
        try {
            bytes = str.getBytes("UTF8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        /**
         * 创建File对象，其中包含文件所在的目录以及文件的命名
         */

        Log.e("FileUtils", "file  " + file.getAbsolutePath());
        // 创建FileOutputStream对象
        FileOutputStream outputStream = null;
        // 创建BufferedOutputStream对象
        BufferedOutputStream bufferedOutputStream = null;
        try {
            // 如果文件存在则删除
//            if (file.exists()) {
//                file.delete();
//            }
//            // 在文件系统中根据路径创建一个新的空文件
//            file.createNewFile();
            // 获取FileOutputStream对象
            outputStream = new FileOutputStream(file, append);
            // 获取BufferedOutputStream对象
            bufferedOutputStream = new BufferedOutputStream(outputStream);
            // 往文件所在的缓冲输出流中写byte数据
            bufferedOutputStream.write(bytes);
            // 刷出缓冲输出流，该步很关键，要是不执行flush()方法，那么文件的内容是空的。
            bufferedOutputStream.flush();
        } catch (Exception e) {
            // 打印异常信息
            e.printStackTrace();
        } finally {
            // 关闭创建的流对象
            if (outputStream != null) {
                try {
                    outputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
    }

    public static void writeToFile(String str, String folderPath, String fileName, boolean append) {
        File file = new File(folderPath,
                fileName);
        writeToFile(str, file, append);
    }


    public static boolean deleteFile(String filePath) {
        File file = new File(filePath);
        if (file.exists()) {
            return file.delete();
        } else {
            Log.e("删除", "不存在 ");
        }
        return false;
    }


    public static File renameFile(File file, String name) {
        if (!file.exists()) {
            return null;
        }

        if (TextUtils.isEmpty(name)) {
            return null;
        }
        return renameFile(file.getAbsoluteFile().getPath(), file.getParent() + "/" + name);
    }

    public static File moveFile(String oldPath, String newPath) {
        return renameFile(oldPath, newPath);
    }

    public static void copyFileUsingFileChannels(File source, File dest) {
        FileChannel inputChannel = null;
        FileChannel outputChannel = null;
        try {
            inputChannel = new FileInputStream(source).getChannel();
            outputChannel = new FileOutputStream(dest).getChannel();
            outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
            inputChannel.close();
            outputChannel.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    //flie：要删除的文件夹的所在位置
    public static void deleteFile(File file) {
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File f = files[i];
                deleteFile(f);
            }
            file.delete();//如要保留文件夹，只删除文件，请注释这行
        } else if (file.exists()) {
            file.delete();
        }
    }


    /**
     * oldPath 和 newPath必须是新旧文件的绝对路径
     */
    private static File renameFile(String oldPath, String newPath) {
        if (TextUtils.isEmpty(oldPath)) {
            return null;
        }

        if (TextUtils.isEmpty(newPath)) {
            return null;
        }
        File oldFile = new File(oldPath);
        File newFile = new File(newPath);
        boolean b = oldFile.renameTo(newFile);
        if (b) {
            return newFile;
        }
        return null;
    }

    /**
     * 通知系统相册更新
     */
    public static void refreshSystemPic(Context context, File destFile) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            insertPicInAndroidQ(context, destFile);
        } else {
            ContentValues value = new ContentValues();
            value.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
            value.put(MediaStore.Images.Media.DATA, destFile.getAbsolutePath());
            context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, value);
            Uri contentUri;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                contentUri = FileProvider.getUriForFile(
                        context,
                        "{applicationId}.fileProvider",
                        destFile
                );
            } else {
                contentUri = Uri.fromFile(new File(destFile.getPath()));
            }
            context.sendBroadcast(
                    new Intent(
                            Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
                            contentUri
                    )
            );
        }
    }


    /**
     * Android Q以后向系统相册插入图片
     */
    @RequiresApi(Build.VERSION_CODES.Q)
    public static void insertPicInAndroidQ(Context context, File insertFile) {
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.DESCRIPTION, insertFile.getName());
        values.put(MediaStore.Images.Media.DISPLAY_NAME, insertFile.getName());
        values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
        values.put(MediaStore.Images.Media.TITLE, "Image.jpg");
        values.put(MediaStore.Images.Media.RELATIVE_PATH, "Pictures/");

        Uri external = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        ContentResolver resolver = context.getContentResolver();
        Uri insertUri = resolver.insert(external, values);
        BufferedInputStream inputStream;
        OutputStream os = null;
        try {
            inputStream = new BufferedInputStream(new FileInputStream(insertFile));
            if (insertUri != null) {
                os = resolver.openOutputStream(insertUri);
            }
            if (os != null) {

                byte[] buffer = new byte[1024 * 4];
                int len = -1;
                while ((len = inputStream.read(buffer)) != -1) {
                    os.write(buffer, 0, len);
                }

                os.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (os != null) {
                    os.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }

        }
    }
}
